<template>
  <div
    class="content-edit"
    @mousedown="mousedownHandleUnStop"
    @drop="dragHandle"
    @dragover="dragoverHandle"
    @dragenter="dragoverHandle"
  >
    <!-- 标尺 -->
    <SketchRule
      v-if="sketchRuleReDraw"
      :thick="thick"
      :scale="scale"
      :width="canvasBox().width"
      :height="canvasBox().height"
      :start-x="startX"
      :start-y="startY"
      :lines="lines"
    />
    <div ref="app" class="edit-screens" @scroll="handleScroll">
      <div
        ref="container"
        class="edit-screen-container"
        :style="{
          width: editCanvasConfig.width * 2 + 'px',
          height: containerWidth,
        }"
      >
        <div
          ref="refSketchRuleBox"
          class="canvas"
          :style="{ marginLeft: '-' + (canvasBox().width / 2 - 25) + 'px' }"
          @mousedown="dragCanvas"
        >
          <div :style="{ pointerEvents: isPressSpace ? 'none' : 'auto' }">
            <!-- 画布主体 -->
            <div id="chart-edit-content">
              <!-- 展示 -->
              <EditRange />
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 工具栏 -->
    <EditTools />
  </div>
</template>

<script>
import keymaster from 'keymaster'
import debounce from 'lodash/debounce'
import throttle from 'lodash/throttle'
import { mapGetters, mapMutations, mapState } from 'vuex'
import { SketchRule } from 'vue3-sketch-ruler'
import { listen } from 'dom-helpers'
import EditRange from './components/EditRange'
import EditTools from './components/EditTools'
import mixins from './mixins/drag'
export default {
  mixins: [mixins],
  components: { SketchRule, EditRange, EditTools },
  computed: {
    ...mapGetters(['editCanvas', 'editCanvasConfig', 'componentList']),
    ...mapState('aside', ['rePositionCanvas']),
    scale () {
      return this.editCanvas.scale
    },
    // 滚动条拖动的高度
    containerWidth () {
      return `${this.editCanvasConfig.height * 2}px`
    }
  },
  data () {
    return {
      sketchRuleReDraw: true,
      startX: 0,
      startY: 0,
      thick: 20,
      lines: { h: [], v: [] },
      isPressSpace: false,
      prevMoveXValue: [0, 0],
      prevMoveYValue: [0, 0]
    }
  },
  mounted () {
    this.$refs.app.addEventListener('wheel', this.handleWheel, { passive: false })
    this.canvasPosCenter()
    this.useAddKeyboard()
  },
  methods: {
    // 重绘标尺
    ...mapMutations('chartEdit', ['setScale', 'removeComponentList']),
    reDraw () {
      this.sketchRuleReDraw = false
      setTimeout(() => {
        this.sketchRuleReDraw = true
      }, 10)
    },
    // 计算画布大小
    canvasBox () {
      const layoutDom = document.querySelector('.content-edit')
      if (layoutDom) {
        // 此处减去滚动条的宽度和高度 
        const scrollW = 20
        return {
          height: layoutDom.clientHeight - scrollW,
          width: layoutDom.clientWidth - scrollW
        }
      }
      return {
        width: this.editCanvasConfig.width,
        height: this.editCanvasConfig.height
      }
    },
    // 拖拽处理
    dragCanvas (e) {
      e.preventDefault()
      e.stopPropagation()
      if (e.which == 2) this.isPressSpace = true
      else if (!window.$KeyboardActive?.space) return
      document.activeElement?.blur()
      const startX = e.pageX
      const startY = e.pageY
      const listenMousemove = listen(window, 'mousemove', (e) => {
        const nx = e.pageX - startX
        const ny = e.pageY - startY

        const [prevMoveX1, prevMoveX2] = this.prevMoveXValue
        const [prevMoveY1, prevMoveY2] = this.prevMoveYValue

        this.prevMoveXValue = [prevMoveX2, nx]
        this.prevMoveYValue = [prevMoveY2, ny]

        this.$refs.app.scrollLeft -=
          prevMoveX2 > prevMoveX1 ? Math.abs(prevMoveX2 - prevMoveX1) : -Math.abs(prevMoveX2 - prevMoveX1)
        this.$refs.app.scrollTop -=
          prevMoveY2 > prevMoveY1 ? Math.abs(prevMoveY2 - prevMoveY1) : -Math.abs(prevMoveY2 - prevMoveY1)
      })

      const listenMouseup = listen(window, 'mouseup', () => {
        listenMousemove()
        listenMouseup()
        this.prevMoveXValue = [0, 0]
        this.prevMoveYValue = [0, 0]
        this.isPressSpace = false
      })
    },
    // 滚动条处理
    handleScroll () {
      if (!this.$refs.app) return
      const screensRect = this.$refs.app.getBoundingClientRect()
      const canvasRect = this.$refs.refSketchRuleBox.getBoundingClientRect()
      // 标尺开始的刻度
      this.startX = (screensRect.left + this.thick - canvasRect.left) / this.scale
      this.startY = (screensRect.top + this.thick - canvasRect.top) / this.scale
    },
    // 滚动居中
    canvasPosCenter () {
      const { width: containerWidth, height: containerHeight } = this.$refs.container.getBoundingClientRect()
      const { width, height } = this.canvasBox()
      this.$refs.app.scrollLeft = containerWidth / 2 - width / 2
      this.$refs.app.scrollTop = containerHeight / 2 - height / 2
    },
    // 处理鼠标拖动
    handleWheel (e) {
      if (e.ctrlKey || e.metaKey) {
        e.preventDefault()
        let resScale = this.scale
        // 放大(200%)
        if (e.wheelDelta >= 0 && this.scale < 2) {
          resScale = this.scale + 0.05
          this.setScale({ scale: resScale })
          return
        }
        // 缩小(10%)
        if (e.wheelDelta < 0 && this.scale > 0.1) {
          resScale = this.scale - 0.05
          this.setScale({ scale: resScale })
        }
      }
    },
    // 鼠标事件
    useAddKeyboard () {
      keymaster('delete', debounce(() => { this.removeComponentList(); return false }, 50))
      keymaster('backspace', debounce(() => { this.removeComponentList(); return false }, 50))
    }
  },
  watch: {
    scale (newValue, oldValue) {
      if (oldValue !== newValue && this.rePositionCanvas) {
        // chartLayoutStore.setItemUnHandle(ChartLayoutStoreEnum.RE_POSITION_CANVAS, false)
        this.handleScroll()
        setTimeout(() => {
          this.canvasPosCenter()
          this.reDraw()
        }, 400)
      } else {
        throttle(this.reDraw, 20)
      }
    }
  },
  destroyed () {
    this.$refs.app.removeEventListener('wheel', this.handleWheel)
  }
}
</script>
<style>
.style-ruler {
  position: absolute;
  z-index: 3;
  width: 100%;
  height: 100%;
  overflow: hidden;
  font-size: 12px;
  pointer-events: none;
  list-style: none;
}
#mb-ruler {
  top: 0;
  left: 0;
}

/* 横线 */
#mb-ruler .v-container .lines .line {
  /* 最大缩放 200% */
  width: 200vw !important;
  border-top: 1px dashed v-bind("themeColor") !important;
}

#mb-ruler .v-container .indicator {
  border-bottom: 1px dashed v-bind("themeColor") !important;
}

/* 竖线 */
#mb-ruler .h-container .lines .line {
  /* 最大缩放 200% */
  height: 200vh !important;
  border-left: 1px dashed v-bind("themeColor") !important;
}

#mb-ruler .h-container .indicator {
  border-left: 1px dashed v-bind("themeColor") !important;
}

/* 坐标数值背景颜色 */
#mb-ruler .indicator .value {
  background-color: rgba(0, 0, 0, 0);
}

/* 删除按钮 */
#mb-ruler .line .del {
  padding: 0;
  color: v-bind("themeColor");
  font-size: 26px;
  font-weight: bolder;
}

#mb-ruler .corner {
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: auto;
  cursor: pointer;
  box-sizing: content-box;
  transition: all 0.2s ease-in-out;
  border-width: 0 !important;
}
</style>
<style lang="scss" scoped>
.content-edit {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
  background-image: linear-gradient(#fafafc 14px, transparent 0),
    linear-gradient(90deg, transparent 14px, #373739 0);
  background-size: 15px 15px, 15px 15px;
  .edit-screens {
    position: absolute;
    width: 100%;
    height: 100%;
    overflow: auto;
    user-select: none;
    padding-bottom: 0px;

    /* firefox */
    scrollbar-color: rgba(144, 146, 152, 0.3) transparent;
    scrollbar-width: thin;

    /* chrome */
    &::-webkit-scrollbar,
    &::-webkit-scrollbar-track-piece {
      background-color: transparent;
    }

    &::-webkit-scrollbar {
      width: 7px;
    }

    &::-webkit-scrollbar-thumb {
      border-radius: 5px;
      background-color: rgba(144, 146, 152, 0.3);
    }
    // 修复右下角白点用的
    &::-webkit-scrollbar-corner {
      background-color: transparent;
    }
    .edit-screen-container {
      position: absolute;
      top: 0;
      left: 0;
      .canvas {
        position: absolute;
        top: 50%;
        left: 50%;
        transform-origin: 50% 0;
        transform: translateY(-50%);

        &:hover {
          cursor: v-bind("cursorStyle");
        }

        &:active {
          cursor: crosshair;
        }
        #chart-edit-content {
          border-radius: 10px;
          overflow: hidden;
          transition: all 0.4s;
          box-shadow: 0 8px 10px rgba(0, 0, 0, 0.0705882353);
        }
      }
    }
  }
  .tool {
    position: relative;
  }
}
</style>